package com.atguigu.spzx.product.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.spzx.model.dto.h5.ProductSkuSearchDto;
import com.atguigu.spzx.model.entity.product.Product;
import com.atguigu.spzx.model.entity.product.ProductDetails;
import com.atguigu.spzx.model.entity.product.ProductSku;
import com.atguigu.spzx.model.vo.h5.ProductSkuDetailVo;
import com.atguigu.spzx.model.vo.h5.ProductSpecValueVo;
import com.atguigu.spzx.model.vo.product.ProductVo;
import com.atguigu.spzx.product.mapper.ProductSkuMapper;
import com.atguigu.spzx.product.service.ProductDetailsService;
import com.atguigu.spzx.product.service.ProductService;
import com.atguigu.spzx.product.service.ProductSkuService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ProductSkuServiceImpl extends ServiceImpl<ProductSkuMapper , ProductSku>
        implements ProductSkuService {
    @Resource
    ProductService productService;
    @Resource
    ProductDetailsService productDetailsService;

    @Override
    public PageInfo<ProductSku> getPageByCondition(Integer pageNum, Integer pageSize, ProductSkuSearchDto productSkuSearchDto) {
        //组装查询条件
//        Page<ProductSku> page = this.page(new Page<>(pageNum, pageSize), queryWrapper);
        //mp只能进行单表的查询  多表联查 必须使用自定义sql实现
        Page<ProductSku> page = new Page<>(pageNum, pageSize);
        //mp如果配置了分页拦截器，自定义mapper方法传入的page对象它会自动拦截解析为limit拼接到sql后
        //如果使用QueryWrapper组装了查询条件，自定义sql中可以调用QueryWrapper对象的方法获取组装的动态sql
        QueryWrapper<ProductSku> queryWrapper = Wrappers.query();//一会再组装查询条件

        /*
            <!--        where t2.category1_id = 1-->
            <!--        and t2.brand_id = 8-->
            <!--        and t1.sku_name like '%8G%'-->
         */
        Long category1Id = productSkuSearchDto.getCategory1Id();
        if(category1Id!=null){
            queryWrapper.eq("t2.category1_id" , category1Id);
        }
        Long category2Id = productSkuSearchDto.getCategory2Id();
        if(category2Id!=null){
            queryWrapper.eq("t2.category2_id" , category2Id);
        }
        Long category3Id = productSkuSearchDto.getCategory3Id();
        if(category3Id!=null){
            queryWrapper.eq("t2.category3_id" , category3Id);
        }
        Long brandId = productSkuSearchDto.getBrandId();
        if(brandId!=null){
            queryWrapper.eq("t2.brand_id" , brandId);
        }
        String keyword = productSkuSearchDto.getKeyword();
        if(!StringUtils.isEmpty(keyword)){
            queryWrapper.like("t1.sku_name" , keyword);
        }
        List<ProductSku> productSkuList= baseMapper.selectSkuPageByCondition(page , queryWrapper);
        //将查询到的分页数据设置到分页对象中
        page.setRecords(productSkuList);


        PageInfo<ProductSku> pageInfo = new PageInfo<>(productSkuList);
        pageInfo.setPages((int) page.getPages());
        pageInfo.setPageNum((int) page.getCurrent());
        pageInfo.setPageSize((int) page.getSize());
        pageInfo.setTotal(page.getTotal());

        return pageInfo;
    }
    @Cacheable(value = "spzx:cache:sku" , key = "#skuId")
    @Override
    public ProductSkuDetailVo findItem(Long skuId) {
        ProductSkuDetailVo productSkuDetailVo = new ProductSkuDetailVo();
        //1、sku数据：product_sku
        ProductSku productSku = this.getById(skuId);
        productSkuDetailVo.setProductSku(productSku);
        //2、spu数据： product   业务类&mapper
        Long spuId = productSku.getProductId();
        Product product = productService.getById(spuId);
        ProductVo productVo = new ProductVo();
        BeanUtils.copyProperties(product , productVo);
        // TODO 还需要查询product的一二三级分类标题 和品牌名称
        productSkuDetailVo.setProduct(productVo);

        //spu数据： 轮播图列表
        productSkuDetailVo.setSliderUrlList(Arrays.asList(product.getSliderUrls().split(",")));
        //spu数据：[{"key":"颜色","valueList":["白色"]},{"key":"内存","valueList":["8G","12G"]}]
        List<ProductSpecValueVo> productSpecValueVos = JSON.parseArray(product.getSpecValue(), ProductSpecValueVo.class);
        productSkuDetailVo.setSpecValueList(productSpecValueVos);
        //3、spu详情图数据： product_details   业务类&mapper
        ProductDetails productDetails = productDetailsService.getById(spuId);//和spu是1:1的映射
        productSkuDetailVo.setDetailsImageUrlList(Arrays.asList(productDetails
                .getImageUrls().split(",")));
        //4、spu下的所有的sku规格属性值和自己id映射的集合：product_sku
        //查询spu下所有的sku
        Map<String, Long> map = this.list(Wrappers.lambdaQuery(ProductSku.class)
                        .eq(ProductSku::getProductId, spuId)
                        .eq(ProductSku::getDeleted, 0)
                        .select(ProductSku::getId, ProductSku::getSkuSpec))
                .stream()
                // 将前面查询的ProductSku对象的List集合 每个对象的skuSpce属性作为键 id作为值存到map中
                .collect(Collectors.toMap(ProductSku::getSkuSpec, ProductSku::getId));


        productSkuDetailVo.setSkuSpecValueMap(map);

        return productSkuDetailVo;
    }
}
